perm filename RECOG1.SAI[SYS,HE] blob
sn#021165 filedate 1973-01-20 generic text, type T, neo UTF8
COMMENT ⊗ VALID 00018 PAGES
RECORD PAGE DESCRIPTION
00001 00001
00005 00002 ENTRY DUMMY
00006 00003 α GENSYM
00007 00004 α TABCOOR
00008 00005 α DET3X3
00009 00006 α INVERT
00010 00007 α HOMO_XFRM
00011 00008 α BESTIN
00013 00009 α INITIALIZE
00014 00010 α MATMULT
00015 00011 α VERT_LINE_PT
00017 00012 α ANGLE
00019 00013 α DIST
00020 00014 α VERT
00021 00015 α PARALLEL
00022 00016 α COLINEAR
00026 00017 α CROSS_PROD
00027 00018 α DOT_PROD
00028 ENDMK
⊗;
ENTRY DUMMY;
BEGIN "RECOG1.SAI"
REQUIRE 250 PNAMES;
REQUIRE "PREAMB.SAI[SYS,HE]" SOURCE_FILE;
REQUIRE "CPXSYM.AUX[SYS,HE]" SOURCE_FILE;
REQUIRE "RECCOM.AUX[SYS,HE]" SOURCE_FILE;
α LOCALS;
INTEGER FLAG,ERRFLAG;
α EXTERNAL PROCEDURES;
ERP ACOS(REAL X);
ERP ATAN(REAL X);
ERP SQRT(REAL X);
ESP PRINTNAME(ITEMVAR X);
α GENSYM;
INTERNAL STRING PROCEDURE GENSYM(INTEGER ITEMVAR X);
BEGIN "GENSYM"
STRING NAME;
NAME←PRINTNAME(X);
IF FLAG
THEN BEGIN
TYPE "GENSYM - PRINTNAME LOSSAGE" EOM;
CALL(0,"EXIT");
END;
RETURN(NAME&CVS(∂(X)←∂(X)+1));
END "GENSYM";
α TABCOOR
the image coordinate system has been flipped right side up,
ergo the SDY hack in line .+10
;
EXTERNAL REAL SDY;
INTERNAL PROCEDURE TABCOOR(SAFE REAL ARRAY ITEMVAR U);
BEGIN "TABCOOR"
INTEGER I;
FOR I←1 S1U 3 DO
BEGIN
∂(U)[I+2]←0.0;
∂(U)[I+2]←∂(U)[I+2]+∂(U)[1]*AI_REC[I,1]
+(SDY-∂(U)[2])*AI_REC[I,2]+AI_REC[I,3];
END;
FOR I←3 S1U 5 DO
∂(U)[I]←∂(U)[I]/∂(U)[5];
∂(U)[5]←0.0;
END "TABCOOR";
α DET3X3;
INTERNAL REAL PROCEDURE DET3X3(REAL ARRAY A);
BEGIN "DET3X3"
REAL V;
V←0.0;
V←V+(A[1,1]*A[2,2]*A[3,3]);
V←V+(A[1,2]*A[2,3]*A[3,1]);
V←V+(A[1,3]*A[3,2]*A[2,1]);
V←V-(A[3,1]*A[2,2]*A[1,3]);
V←V-(A[3,2]*A[2,3]*A[1,1]);
V←V-(A[3,3]*A[1,2]*A[2,1]);
RETURN (V);
END "DET3X3";
α INVERT;
INTERNAL PROCEDURE INVERT(REAL ARRAY A, AI);
BEGIN "INVERT"
REAL ARRAY B[1:3,1:3],ADJA[1:4,1:4];
INTEGER I,J,K,L,M,N; REAL DET;
FOR I←1 S1U 4 DO
FOR J←1 S1U 4 DO
BEGIN
M←N←1;
FOR K←1 S1U 4 DO
FOR L←1 S1U 4 DO
IF K≠I ∧ L≠J THEN
BEGIN
B[M,N]←A[K,L];
N←(N+1) MOD 4;
IF N=0 THEN BEGIN
N←N+1; M←(M+1) MOD 4;
END;
END;
ADJA[I,J]←((-1)↑(I+J))*DET3X3(B);
END;
DET←ADJA[4,4];
FOR I←1 S1U 4 DO
FOR J←1 S1U 4 DO
AI[I,J]←ADJA[J,I]/DET;
RETURN;
END "INVERT";
α HOMO_XFRM
transform P by the 4X4 homogeneous transformation matrix T
;
INTERNAL PROCEDURE HOMO_XFRM(SAFE REAL ARRAY P,T);
BEGIN "HOMO_XFRM"
SAFE REAL ARRAY TEMP[1:4];
INTEGER I,J;
FOR I←1 S1U 4 DO
BEGIN
TEMP[I]←0.0;
FOR J←1 S1U 4 DO
TEMP[I]←TEMP[I]+T[I,J]*P[J];
END;
FOR J←1 S1U 4 DO P[J]←TEMP[J]/TEMP[4];
END "HOMO_XFRM";
α BESTIN
finds the "best intersection" of 2 skew lines
;
INTERNAL PROCEDURE BESTIN(SAFE REAL ARRAY PJ,QJ,PK,QK,INT;
REFERENCE REAL MISDIS);
BEGIN "BESTIN"
SAFE REAL ARRAY VJ[1:3],VK[1:3],DIS[1:3],PD[1:3];
REAL A,B,C,D,E,DET,TJ,TK; INTEGER I;
A←B←C←D←E←MISDIS←0;
FOR I←1 STEP 1 UNTIL 3 DO
BEGIN
PD[I]←PK[I]-PJ[I];
VJ[I]←QJ[I]-PJ[I];
VK[I]←QK[I]-PK[I];
A←A+VJ[I]↑2;
B←B-VJ[I]*VK[I];
C←C+VK[I]↑2;
D←D+PD[I]*VJ[I];
E←E-PD[I]*VK[I];
END;
DET←A*C-B↑2;
TJ←(C*D-B*E)/DET;
TK←(A*E-B*D)/DET;
FOR I←1 STEP 1 UNTIL 3 DO
BEGIN
INT[I]←(PJ[I]+PK[I]+TK*VK[I]+TJ*VJ[I])/2;
DIS[I]←TJ*VJ[I]-TK*VK[I]-PD[I];
MISDIS←MISDIS+DIS[I]↑2;
END;
MISDIS←SQRT(MISDIS);
RETURN;
END "BESTIN";
α INITIALIZE
initializes a 4X4 matrix to the identity matrix
;
INTERNAL PROCEDURE INITIALIZE(SAFE REAL ARRAY A);
BEGIN "INITIALIZE"
INTEGER I,J;
FOR I←1 STEP 1 UNTIL 4 DO
FOR J←1 STEP 1 UNTIL 4 DO
IF I=J THEN A[I,J]←1.0 ELSE A[I,J]←0.0;
RETURN ;
END "INITIALIZE";
α MATMULT
multiplies 2 nXn matrices
;
INTERNAL PROCEDURE MATMULT(SAFE REAL ARRAY A,B,C;INTEGER N);
BEGIN "MATMULT"
INTEGER I,J,K; REAL SUM;
SAFE REAL ARRAY D[1:N,1:N];
FOR I←1 STEP 1 UNTIL N DO
FOR J←1 STEP 1 UNTIL N DO
BEGIN
SUM←0.0;
FOR K←1 STEP 1 UNTIL N DO
SUM←SUM+A[I,K]*B[K,J];
D[I,J]←SUM;
END;
FOR I←1 STEP 1 UNTIL N DO
FOR J←1 STEP 1 UNTIL N DO
C[I,J]←D[I,J];
RETURN;
END "MATMULT";
α VERT_LINE_PT
T is top and B is bottom image vertex assumed to lie
on a line normal to the table plane.
Returns with the true 3-d coords stuffed into T.
;
INTERNAL PROCEDURE VERT_LINE_PT(SAFE REAL ARRAY ITEMVAR T,B);
BEGIN "VERT_LINE_PT"
SAFE REAL ARRAY TOP,INT,P,BASE[1:3];
INTEGER I;REAL MISDIS;
TYPE "VERT_LINE_PT - ENTERED" EOM;
FOR I←1 S1U 2 DO
BEGIN
TOP[I]←∂(T)[I+2];
P[I]←BASE[I]←∂(B)[I+2];
END;
TOP[3]←BASE[3]←∂(B)[5];
P[3]←∂(B)[5]+1.0;
TYPE TAB&"TOP "&CVG(TOP[1])&" "&CVG(TOP[2])&" "&CVG(TOP[3]) EOM;
TYPE TAB&"LENS_REC "&CVG(LENS_REC[1])&" "&CVG(LENS_REC[2])&" "&
CVG(LENS_REC[3]) EOM;
TYPE TAB&"BASE "&CVG(BASE[1])&" "&CVG(BASE[2])&" "&CVG(BASE[3])
EOM;
TYPE TAB&"P "&CVG(P[1])&" "&CVG(P[2])&" "&CVG(P[3]) EOM;
BESTIN(TOP,LENS_REC,BASE,P,INT,MISDIS);
TYPE TAB&"VLP "&PRINTNAME(T)&" "&PRINTNAME(B)&CVG(INT[3]) EOM;
FOR I← 1 S1U 3 DO
∂(T)[I+2]←INT[I];
RETURN;
END "VERT_LINE_PT";
α ANGLE
returns the angle in degrees of the angle formed by P1,P2,P3.
DIMS is the number of dimensions of the point.;
INTERNAL REAL PROCEDURE ANGLE(SAFE REAL ARRAY ITEMVAR P1,P2,P3;
INTEGER DIMS);
BEGIN "ANGLE"
SAFE REAL ARRAY V1,V2[1:3];
INTEGER I;REAL MSV1,MSV2,X,DOT;
DOT←MSV1←MSV2←0.0;
IF DIMS=3 THEN
FOR I←1 S1U 3 DO
BEGIN
V1[I]←∂(P1)[I+2]-∂(P2)[I+2];
V2[I]←∂(P3)[I+2]-∂(P2)[I+2];
DOT←DOT+V1[I]*V2[I];
MSV1←MSV1+V1[I]↑2;
MSV2←MSV2+V2[I]↑2;
END
ELSE IF DIMS=2 THEN
FOR I←1 S1U 2 DO
BEGIN
V1[I]←∂(P1)[I]-∂(P2)[I];
V2[I]←∂(P3)[I]-∂(P2)[I];
DOT←DOT+V1[I]*V2[I];
MSV1←MSV1+V1[I]↑2;
MSV2←MSV2+V2[I]↑2;
END
ELSE IF DIMS=4 THEN
FOR I←1 S1U 3 DO
BEGIN
V1[I]←GLB ∂(P1)[I]-GLB ∂(P2)[I];
V2[I]←GLB ∂(P3)[I]-GLB ∂(P2)[I];
DOT←DOT+V1[I]*V2[I];
MSV1←MSV1+V1[I]↑2;
MSV2←MSV2+V2[I]↑2;
END
ELSE TYPE "ANGLE - WRONG NUMBER OF DIMENSIONS"
EOM;
X←DOT/SQRT(MSV1*MSV2);
X←57.3*ACOS(X);
RETURN(X);
END "ANGLE";
α DIST
returns the image distance between two points in raster units.
;
INTERNAL REAL PROCEDURE DIST(SAFE REAL ARRAY ITEMVAR P1,P2);
BEGIN "DIST"
REAL X;
X←SQRT((∂(P1)[1]-∂(P2)[1])↑2+(∂(P1)[2]-∂(P2)[2])↑2);
RETURN (X);
END "DIST";
α VERT
Is edge E approximately vertical in the projection?;
INTERNAL BOOLEAN PROCEDURE VERT(ITEMVAR E);
BEGIN "VERT"
SAFE REAL ARRAY ITEMVAR P1,P2;
SET ES;
REAL A,B,C,D,VERTES;
ES←(ENDPT⊗E);
P1←LOP(ES);
P2←COP(ES);
A←∂(P2)[2]-∂(P1)[2];
B←∂(P1)[1]-∂(P2)[1];
D←SQRT(A↑2 + B↑2);
A←A/D;
B←B/D;
VERTES←ABS(A+B);
IF .900 < VERTES < 1.100
THEN BEGIN
TYPE "VERT - "&PRINTNAME(E)&" (T "&CVG(VERTES)&")" EOM;
RETURN (TRUE);
END
ELSE BEGIN
TYPE "VERT - "&PRINTNAME(E)&" (F "&CVG(VERTES)&")" EOM;
RETURN (FALSE);
END;
END "VERT";
α PARALLEL
returns true if 2 lines are parallel in the projection.;
INTERNAL BOOLEAN PROCEDURE PARALLEL(ITEMVAR L1,L2);
BEGIN "PARALLEL"
SET S;
SAFE REAL ARRAY ITEMVAR X,Y,Z,W;
REAL SLOPE1,SLOPE2;
IF VERT(L1) ∧ VERT(L2)
THEN RETURN (TRUE);
S←ENDPT⊗L1;
X←LOP(S);
Y←COP(S);
S←ENDPT⊗L2;
Z←LOP(S);
W←COP(S);
S←PHI;
SLOPE1←(∂(X)[2]-∂(Y)[2])/(∂(X)[1]-∂(Y)[1]);
SLOPE2←(∂(Z)[2]-∂(W)[2])/(∂(Z)[1]-∂(W)[1]);
IF 57.3*ABS(ATAN(SLOPE1)-ATAN(SLOPE2))<PARAL1
THEN RETURN (TRUE)
ELSE RETURN (FALSE);
END "PARALLEL";
α COLINEAR
determines if two lines are colinear by measuring
the error of the inner endpoints from the line defined by
the outer endpoints of U and V.
;
INTERNAL BOOLEAN PROCEDURE COLINEAR(ITEMVAR U,V);
BEGIN "COLINEAR"
SET S;
SAFE REAL ARRAY ITEMVAR X,Y,W,Z,PU,PV;
REAL A,B,C,D,DIST1,DIST2,UDIST,VDIST,TDIST,ERROR,UERROR,VERROR;
DEFINE
XX(Z)=<∂(Z)[1]>,
YY(Z)=<∂(Z)[2]>,
EQUATION(Z)=<ABS(A*XX(Z) + B*YY(Z) +C)>;
TYPE "COLINEAR - "&PRINTNAME(U)&","&PRINTNAME(V) EOM;
S←(ENDPT⊗U);
X←LOP(S);
Y←COP(S);
DIST1←DIST(X,Y);
S←(ENDPT⊗V);
Z←LOP(S);
W←COP(S);
DIST2←DIST(Z,W);
S←PHI;
IF DIST2>DIST1
THEN BEGIN
X↔Z;
Y↔W;
END;
IF DIST(Z,X)<DIST(W,X)
THEN Z↔W;
IF DIST(X,W)<DIST(Y,W)
THEN X↔Y;
PU←X; PV←Z;
α ARE LINES TOO SMALL WRT CAMERA GRID ??;
IF ABS(∂(X)[1]-∂(Y)[1])<2.0
THEN IF ABS(∂(Z)[1]-∂(W)[1])<2.0 ∧
ABS(∂(Z)[1]-∂(X)[1])<5.0
THEN BEGIN TYPE TAB&"(SMALL) TRUE" EOM; RETURN (TRUE); END
ELSE BEGIN TYPE TAB&"(SMALL) FALSE" EOM;RETURN (FALSE); END;
IF ¬PARALLEL(U,V)
THEN BEGIN
TYPE TAB&"(¬PARALLEL) FALSE" EOM;
RETURN (FALSE);
END;
α NOW GET THE SLOPE AND EQUATION OF LINE PU→PV
A*X+B*Y+C=0 WHERE A,B ARE NORMALIZED COEFFICIENTS,
I.E. A←DELTA Y, B←-DELTA X, D←SQRT(A↑2 + B↑2), A←A/D, B←B/D;
A←YY(PU)-YY(PV);
B←XX(PV)-XX(PU);
D←SQRT(A↑2 + B↑2);
A←A/D;
B←B/D;
C← - A*XX(PU) - B*YY(PU);
UDIST←DIST(X,Y);
VDIST←DIST(W,Z);
TDIST←UDIST+VDIST;
UERROR←EQUATION(Y);
VERROR←EQUATION(W);
ERROR←.25*TDIST/2;
α TYPEOUT SHOULD SHOW VALUES ≤ 1.0 FOR BOTH;
IF UERROR≤ERROR ∧ VERROR≤ERROR
THEN BEGIN
TYPE TAB&"("&CVG(UERROR/ERROR)&","&CVG(VERROR/ERROR)&") TRUE" EOM;
RETURN(TRUE);
END
ELSE BEGIN
TYPE TAB&"FALSE" EOM;
RETURN(FALSE);
END;
END "COLINEAR";
α CROSS_PROD
returns AXB in CP;
INTERNAL PROCEDURE CROSS_PROD(REFERENCE SAFE REAL ARRAY A,B,CP);
BEGIN "CROSS_PROD"
CP[1]←A[2]*B[3]-A[3]*B[2];
CP[2]←A[3]*B[1]-A[1]*B[3];
CP[3]←A[1]*B[2]-A[2]*B[1];
RETURN;
END "CROSS_PROD";
α DOT_PROD
value is the dot product of vectors V1 and V2.;
INTERNAL REAL PROCEDURE DOT_PROD(SAFE REAL ARRAY V1,V2);
BEGIN "DOT_PROD"
REAL DP; INTEGER I;
DP←0.0;
FOR I←1 STEP 1 UNTIL 3 DO
DP←DP+V1[I]*V2[I];
RETURN (DP);
END "DOT_PROD";
END "RECOG1.SAI";